﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace System.Web.Mvc
{
	public static partial class Holovacs
	{
		public static HtmlString CheckListFor<TModel, TKey, TProperty>(
			this HtmlHelper<TModel> htmlHelper,
			Expression<Func<TModel, IEnumerable<TKey>>> forExpression,
			IEnumerable<TProperty> enumeratedItems,
			Func<TProperty, TKey> idExpression,
			Property<TProperty> displayExpression,
			Property<TProperty> titleExpression,
			object htmlAttributes,
            bool addSelectAllBox) where TModel : class
		{
			//initialize values
			var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
			var propertyName = metaData.PropertyName;
			var propertyValue = (IEnumerable<TKey>)htmlHelper.ViewData.Eval(propertyName);
			var enumeratedType = typeof(TProperty);

			//build the select tag
			var returnText = string.Format("<ul id=\"CheckList_{0}\"", propertyName);
			if (htmlAttributes != null)
			{
				foreach (var kvp in htmlAttributes.GetType().GetProperties()
				 .ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
				{
					returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
					 HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
				}
			}
			returnText += ">\n";

            if (addSelectAllBox)
            {
                returnText += string.Format("<li class=\"metaCheckBox\"><input id=\"SelectAll_{0}\" type=\"checkbox\" class=\"selectAll\" />Select All</li>\n", propertyName);
            }

			//build the options tags
			foreach (TProperty listItem in enumeratedItems)
			{
				var idValue = (TKey)idExpression(listItem);
				var displayValue = displayExpression(listItem).ToStringOrEmpty();
				var titleValue = titleExpression(listItem).ToStringOrEmpty();
				returnText += string.Format("<li title=\"{1}\"><input name=\"{0}\" type=\"checkbox\" value=\"{2}\" ",
					HttpUtility.HtmlEncode(propertyName),
					HttpUtility.HtmlEncode(titleValue),
					HttpUtility.HtmlEncode(idValue));
				if (propertyValue.Contains<TKey>(idValue))
				{
					returnText += " checked=\"checked\"";
				}
				returnText += string.Format(">{0}</li>\n", HttpUtility.HtmlEncode(displayValue));
			}

			//close the select tag
			returnText += "</ul>";
			return new HtmlString(returnText);
		}

		public static HtmlString CheckListFor<TModel, TKey, TProperty>(
			this HtmlHelper<TModel> htmlHelper,
			Expression<Func<TModel, IEnumerable<TKey>>> forExpression,
			IEnumerable<TProperty> enumeratedItems,
			Func<TProperty, TKey> idExpression,
			Property<TProperty> displayExpression,
			Property<TProperty> titleExpression) where TModel : class
		{
			return htmlHelper.CheckListFor(
				forExpression,
				enumeratedItems,
				idExpression,
				displayExpression,
				titleExpression,
				null,
				false);
		}

	}
}
